package me.sealer.proxy.utils;

import me.sealer.proxy.MyCglibProxy;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;

/**
 * Created by sealer
 * On 16/10/10.
 * email 1178884049@qq.com
 */
public class CglibProxyTestFactory {

    public CglibProxyTestFactory() {
    }

    /**
     * Create a proxy using param callback. The target class
     * must have a default zero-argument constructor.
     *
     * @param targetClass the super class of the proxy
     * @return a new proxy for a target class instance
     */
    private static <T> T createProxy(Class<T> targetClass, Callback callback) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetClass);
        enhancer.setCallback(callback);
        return (T) enhancer.create();
    }

    //带CallbackFilter
    private static <T> T createProxy2(Class<T> targetClass, CallbackFilter callbackFilter) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetClass);
        enhancer.setCallbackFilter(callbackFilter);
        Callback createCallback = new MyCglibProxy();
        Callback deleteCallback = new MyCglibProxy();
        Callback updateCallback = new MyCglibProxy();
        Callback queryCallback = NoOp.INSTANCE;
        Callback[] callbacks = new Callback[]{createCallback, deleteCallback, updateCallback, queryCallback};
        enhancer.setCallbacks(callbacks);
        return (T) enhancer.create();
    }

    public static <T> T getProxyInstance(Class<T> targetClass, Callback callback) {
        return createProxy(targetClass, callback);
    }

    public static <T> T getProxyInstance2(Class<T> targetClass, CallbackFilter callbackFilter) {
        return (T) createProxy2(targetClass, callbackFilter);
    }
}
